from django.http import HttpResponse
from django.shortcuts import render

from book.models import BookInfo


# Create your views here.
def index(request):
    return HttpResponse('index')
   #数据库操作-增、删、改  #python manage.py shell，可以快速验证
# from book.models import BookInfo,PeopleInfo
# #增
# #1
# book = BookInfo(
#         name='python入门',
#        pub_date='2010-1-1'   )
# book.save()
# #2 objects.create
# PeopleInfo.objects.create(
#     name='itheima',
#     book=book)
# #改
# #1  objects.get(
# person = PeopleInfo.objects.get(id=20)
# person.name = 'itcast'
# person.save()
# #2
# PeopleInfo.objects.filter(name='itcast').update(name='传智播客')
# #删
# #1
# person = PeopleInfo.objects.get(id=18)
# person.delete()
# #2
# BookInfo.objects.filter(id=5).delete()

#####数据库操作-查询
#1
# try:
#     BookInfo.objects.get(id=1) #查一个
# except BookInfo.DoesNotExist:
#       print("结果不存在")
# #2
# BookInfo.objects.all()
# #3 count
# BookInfo.objects.all().count()
#filter过滤,sql中where
#filter过滤出多个结果
#exclude排除掉符合条件剩下的结果--having
#get过滤单一结果
"""
属性名称__比较运算符=值

# 属性名称和比较运算符间使用两个下划线，所以属性名不能包括多个下划线
查询编号为1的图书
查询书名包含'湖'的图书
查询书名以'部'结尾的图书
查询书名为空的图书
查询编号为1或3或5的图书
查询编号大于3的图书
查询1980年发表的图书
查询1990年1月1日后发表的图书
1）相等

exact：表示判等。

例：查询编号为1的图书。

BookInfo.objects.filter(id__exact=1)
可简写为：
BookInfo.objects.filter(id=1)
2）模糊查询

contains：是否包含。

说明：如果要包含%无需转义，直接写即可。

例：查询书名包含'传'的图书。

BookInfo.objects.filter(name__contains='传')
<QuerySet [<BookInfo: 射雕英雄传>]>
startswith、endswith：以指定值开头或结尾。

例：查询书名以'部'结尾的图书

>>> BookInfo.objects.filter(name__endswith='部')
<QuerySet [<BookInfo: 天龙八部>]>
以上运算符都区分大小写，在这些运算符前加上i表示不区分大小写，如iexact、icontains、istartswith、iendswith.

3） 空查询

isnull：是否为null。

例：查询书名为空的图书。

>>> BookInfo.objects.filter(name__isnull=True)
<QuerySet []>
4） 范围查询

in：是否包含在范围内。

例：查询编号为1或3或5的图书

>>> BookInfo.objects.filter(id__in=[1,3，5])
<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 笑傲江湖>]>
5）比较查询

gt大于 (greater then)
gte大于等于 (greater then equal)
lt小于 (less then)
lte小于等于 (less then equal)
例：查询编号大于3的图书

BookInfo.objects.filter(id__gt=3)
不等于的运算符，使用exclude()过滤器。

例：查询编号不等于3的图书

>>> BookInfo.objects.exclude(id=3)

6）日期查询

year、month、day、week_day、hour、minute、second：对日期时间类型的属性进行运算。

例：查询1980年发表的图书。

>>> BookInfo.objects.filter(pub_date__year=1980)
<QuerySet [<BookInfo: 射雕英雄传>]>
例：查询1990年1月1日后发表的图书。

>>> BookInfo.objects.filter(pub_date__gt='1990-1-1')
<QuerySet [<BookInfo: 笑傲江湖>]>
"""
######之前的查询都是对象的属性与常量值比较，两个属性怎么比较呢
"""
F
例：查询阅读量大于等于评论量的图书。

>>> from django.db.models import F
>>> BookInfo.objects.filter(readcount__gte=F('commentcount'))
<QuerySet [<BookInfo: 雪山飞狐>]>
可以在F对象上使用算数运算。

例：查询阅读量大于2倍评论量的图书。

>>> BookInfo.objects.filter(readcount__gt=F('commentcount')*2)
<QuerySet [<BookInfo: 雪山飞狐>]>

Q
多个过滤器逐个调用表示逻辑与关系，同sql语句中where部分的and关键字。并且

>>> BookInfo.objects.filter(readcount__gt=20,id__lt=3)
<QuerySet [<BookInfo: 天龙八部>]>

或者

>>> BookInfo.objects.filter(readcount__gt=20).filter(id__lt=3)
<QuerySet [<BookInfo: 天龙八部>]>
如果需要实现逻辑或or的查询，需要使用Q()对象结合|运算符，Q对象被义在django.db.models中
from djingo.db.models import Q
BookInfo.objects.filter(readcount__gt=20).filter(id__lt=3)
Q(属性名__运算符=值)
例：查询阅读量大于20的图书，改写为Q对象如下。

BookInfo.objects.filter(Q(readcount__gt=20))
Q对象可以使用&、|连接，&表示逻辑与，|表示逻辑或。

例：查询阅读量大于20，或编号小于3的图书，只能使用Q对象实现

>>> BookInfo.objects.filter(Q(readcount__gt=20)|Q(id__lt=3))
<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>, <BookInfo: 雪山飞狐>]>
Q对象前可以使用~操作符，表示非not。

例：查询编号不等于3的图书。

>>> BookInfo.objects.filter(~Q(id=3))
<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>, <BookInfo: 雪山飞狐>]>
"""
#####聚合函数和排序函数
"""
使用aggregate()过滤器调用聚合函数。聚合函数包括：Avg平均，Count数量，Max最大，Min最小，Sum求和，被定义在django.db.models中。

例：查询图书的总阅读量。

>>> from django.db.models import Sum
>>> BookInfo.objects.aggregate(Sum('readcount'))
{'readcount__sum': 126}
注意aggregate的返回值是一个字典类型，格式如下：

  {'属性名__聚合类小写':值}

  如:{'readcount__sum': 126}
使用count时一般不使用aggregate()过滤器。

例：查询图书总数。

BookInfo.objects.count()
注意count函数的返回值是一个数字。

# 默认升序
>>> BookInfo.objects.all().order_by('readcount')
<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 笑傲江湖>, <BookInfo: 天龙八部>, <BookInfo: 雪山飞狐>]>


# 降序
>>> BookInfo.objects.all().order_by('-readcount')
<QuerySet [<BookInfo: 雪山飞狐>, <BookInfo: 天龙八部>, <BookInfo: 笑傲江湖>, <BookInfo: 射雕英雄传>]>
"""
#####级联查询,多表
"""
查询书籍为1的所有人物信息
查询人物为1的书籍信息
由一到多的访问语法：

一对应的模型类对象.多对应的模型类名小写_set 例：
>>> book = BookInfo.objects.get(id=1)
>>> book.peopleinfo_set.all()
<QuerySet [<PeopleInfo: 郭靖>, <PeopleInfo: 黄蓉>, <PeopleInfo: 黄药师>, <PeopleInfo: 欧阳锋>, <PeopleInfo: 梅超风>]>
由多到一的访问语法:

多对应的模型类对象.多对应的模型类中的关系类属性名 例：

person = PeopleInfo.objects.get(id=1)
person.book
<BookInfo: 射雕英雄传>
访问一对应的模型类关联对象的id语法:

多对应的模型类对象.关联类属性_id

例：
>>> person = PeopleInfo.objects.get(id=1)
>>> person.book_id
1
#过滤
由多模型类条件查询一模型类数据:

语法如下：

关联模型类名小写__属性名__条件运算符=值
注意：如果没有"__运算符"部分，表示等于。

查询图书，要求图书人物为"郭靖"
查询图书，要求图书中人物的描述包含"八"
例：

查询图书，要求图书人物为"郭靖"

>>> book = BookInfo.objects.filter(peopleinfo__name='郭靖')
>>> book
<QuerySet [<BookInfo: 射雕英雄传>]>
查询图书，要求图书中人物的描述包含"八"

>>> book = BookInfo.objects.filter(peopleinfo__description__contains='八')
>>> book
<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>]>
由一模型类条件查询多模型类数据:

语法如下：

一模型类关联属性名__一模型类属性名__条件运算符=值
注意：如果没有"__运算符"部分，表示等于。

查询书名为“天龙八部”的所有人物
查询图书阅读量大于30的所有人物
例：

查询书名为“天龙八部”的所有人物。

>>> people = PeopleInfo.objects.filter(book__name='天龙八部')
>>> people
<QuerySet [<PeopleInfo: 乔峰>, <PeopleInfo: 段誉>, <PeopleInfo: 虚竹>, <PeopleInfo: 王语嫣>]>
查询图书阅读量大于30的所有人物

>>> people = PeopleInfo.objects.filter(book__readcount__gt=30)
>>> people
<QuerySet [<PeopleInfo: 乔峰>, <PeopleInfo: 段誉>, <PeopleInfo: 虚竹>, <PeopleInfo: 王语嫣>, <PeopleInfo: 胡斐>, 

"""